﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Text.RegularExpressions;
using System.Drawing;

namespace Pixysoft.RTF
{
    class RtfUtility
    {
        public static string GetColoursFromRtf(IRtfColorTable colorTable, string rtf)
        {
            Regex regex = new Regex("\\{\\\\colortbl ;(?<colour>\\\\red(?<red>\\d{0,3})\\\\green(?<green>\\d{0,3})\\\\blue(?<blue>\\d{0,3});)*\\}");

            Match matchResults = regex.Match(rtf);

            Dictionary<int, int> replaces = new Dictionary<int, int>();

            while (matchResults.Success)
            {
                Group GroupObj = matchResults.Groups["red"];

                if (GroupObj.Success)
                {
                    for (int i = 0; i < GroupObj.Captures.Count; i++)
                    {
                        int redval, greenval, blueval;
                        if (int.TryParse(matchResults.Groups["red"].Captures[i].Value, out redval) &&
                            int.TryParse(matchResults.Groups["green"].Captures[i].Value, out greenval) &&
                            int.TryParse(matchResults.Groups["blue"].Captures[i].Value, out blueval))
                        {
                            Color c = Color.FromArgb(redval, greenval, blueval);
                            int count = colorTable.ColorTableList.Length;
                            int index = colorTable.IndexOf(c);
                            if ((i + 1) == index)
                            {
                                continue;
                            }
                            replaces.Add(i + 1, index);
                        }
                    }
                }
                matchResults = matchResults.NextMatch();
            }
            if (replaces.Count > 0)
            {

                //delegate string MatchEvaluator(System.Text.RegularExpressions.Match match)
                rtf = Regex.Replace(rtf, "(?:\\\\cf)([0-9]{1,2})", delegate(Match match)
                                                                       {
                                                                           int val;
                                                                           if (int.TryParse(match.Groups[1].Value, out val) && val > 0)
                                                                           {
                                                                               if (replaces.ContainsKey(val))
                                                                               {
                                                                                   return string.Format(@"\cf{0}", replaces[val]);
                                                                               }
                                                                           }
                                                                           return match.Value;
                                                                       });

                //delegate string MatchEvaluator(System.Text.RegularExpressions.Match match)
                rtf = Regex.Replace(rtf, "(?:\\\\highlight)([0-9]{1,2})", delegate(Match match)
                                                                       {
                                                                           int val;
                                                                           if (int.TryParse(match.Groups[1].Value, out val) && val > 0)
                                                                           {
                                                                               if (replaces.ContainsKey(val))
                                                                               {
                                                                                   return string.Format(@"\highlight{0}", replaces[val]);
                                                                               }
                                                                           }
                                                                           return match.Value;
                                                                       });

            }
            return rtf;
        }

        public static string GetFontsFromRtf(IRtfFontTable fontTable, string rtf)
        {
            Regex regex = new Regex(@"\{\\fonttbl(?<raw>\{\\f(?<findex>\d{1,3}) ?\\(?<fstyle>fswiss|fnil|froman|fmodern|fscript|fdecor|ftech|fbidi) ?(?<fprq>\\fprq\d{1,2} ?)?(?<fcharset>\\fcharset\d{1,3})? (?<FONT>[\w -]+);\})+\}\r?\n", RegexOptions.Multiline);

            Match matchResults = regex.Match(rtf);

            Dictionary<int, int> replaces = new Dictionary<int, int>();

            Group groupObj = matchResults.Groups["raw"];

            for (int i = 0; i < groupObj.Captures.Count; i++)
            {
                string raw = groupObj.Captures[i].Value;
                //string font = MatchResults.Groups["FONT"].Captures[newdocindex].Value;
                Capture cap = matchResults.Groups["findex"].Captures[i];

                //have to replace findex with {0}
                raw = string.Concat("{", Regex.Replace(raw, "\\{\\\\f\\d{1,3}", "{\\f{0}"), "}");

                string curdocstringindex = matchResults.Groups["findex"].Captures[i].Value;


                int sourceindex;
                if (int.TryParse(curdocstringindex, out sourceindex))
                {

                    int destinationindex = fontTable.IndexOfRawFont(raw);
                    if (destinationindex != sourceindex)
                    {
                        replaces.Add(sourceindex, destinationindex);
                    }
                }
            }
            if (replaces.Count > 0)
            {


                rtf = Regex.Replace(rtf, "(?<!\\{)(\\\\f)(\\d{1,3})( ?|\\\\)", delegate(Match match)
                                                                       {
                                                                           int sourceindex2;
                                                                           if (int.TryParse(match.Groups[2].Value, out sourceindex2))
                                                                           {
                                                                               if (replaces.ContainsKey(sourceindex2))
                                                                               {
                                                                                   string rep = string.Format("\\f{0}{1}", replaces[sourceindex2], match.Groups[3].Value);
                                                                                   return rep;
                                                                               }
                                                                           }
                                                                           return match.Value;
                                                                       });

            }
            return rtf;
        }

        public static string GetConcentratedText(string rtf)
        {
            string find = @"\viewkind4";
            int start = rtf.IndexOf(find);
            start = rtf.IndexOf("\\pard", start);
            int end = rtf.LastIndexOf("}");
            int end2 = rtf.LastIndexOf("\\par");
            if (end2 > 0 && ((end - end2) < 8))
            {
                end = end2;
            }
            return rtf.Substring(start + 5, end - start - 5);
        }
    }
}
